package org.example.dynamic.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import org.example.dynamic.enetity.SubCode;
import org.example.dynamic.mapper.DynamicCodeMapper;
import org.example.dynamic.mapper.SubCodeMapper;
import org.example.dynamic.service.impl.IDynamicCodeServiceImpl;
import org.example.dynamic.enetity.DynamicCode;
import org.example.dynamic.util.BaseException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.util.*;


@Service
public class DynamicCodeService extends ServiceImpl<DynamicCodeMapper, DynamicCode> implements IDynamicCodeServiceImpl {

    private static final long CODE_UUID = System.nanoTime();
    private static final int CODE_LENGTH = 8;
    private static final int width = 200; // 二维码的宽度
    private static final int height = 200; // 二维码的高度
    @Resource
    SubCodeMapper subCodeMapper;
    /**
     * 新建数据信息
     * @param dynamic
     * @return
     */
    public String createDynamicCode(DynamicCode dynamic) {
        String code;
        do {
            code = generateRandomCode();
        } while (findByShortCode(code).isPresent());

        dynamic.setCode(code);
//        dynamic.setCount(dynamic.getSubCodeList().size());

        // 组装数据
        dynamic.setId(CODE_UUID);
        // 创建无状态时，则为发布状态
        if (dynamic.getStatus() == 0) {
            dynamic.setStatus(2);
        }
        this.baseMapper.insert(dynamic);

        // 存储子项信息
//        disposeSubCodeData(dynamic);

        return code;
    }

    /**
     * 添加子码信息
     * @param dynamicCode
     */
    public void disposeSubCodeData(DynamicCode dynamicCode) {
        if (!dynamicCode.getSubCodeList().isEmpty()) {
            dynamicCode.getSubCodeList().forEach(d -> {
                d.setId(CODE_UUID);
                d.setShortCode(dynamicCode.getCode());
//                baseMapper.insert(d);
            });
        }
    }

    public static void main(String[] args) {
        String rootPath = File.separator;
        System.out.println(rootPath);
    }

    /**
     * 图片转码
     * 将活码图片，存放到服务器，之后直接读取图片
     * @param code
     * @return
     * @throws WriterException
     * @throws IOException
     */
    @Override
    public byte[] generateQRCode(String code) {
        // 根据code查询活码是否存在
        LambdaQueryWrapper<SubCode> queryWrapper = new LambdaQueryWrapper<SubCode>().eq(SubCode::getShortCode, code);
        List<SubCode> subCodes = subCodeMapper.selectList(queryWrapper);
        if (subCodes == null) {
            throw new BaseException("未查询到对应信息");
        }
        // 定义输出流
        ByteArrayOutputStream os = new ByteArrayOutputStream();

        for (SubCode s : subCodes) {
            if (s.getPredictVisitCount() >= s.getVisitCount()) {
                try {
                    if (s.getType() == 1 || s.getType() == 2) {
                        // 图片
                        String url = s.getMessage();
//                        String url = "http://localhost:8106/images/1741245084732_8d48f4db-b1cd-407a-b70b-250360c187e2.png";
                        QRCodeWriter writer = new QRCodeWriter();
                        BitMatrix matrix = null;
                        matrix = writer.encode(url, BarcodeFormat.QR_CODE, width, height);
                        // 定义输出文件流
                        MatrixToImageWriter.writeToStream(matrix, "PNG", os);
                    } else {
                        String rootPath = System.getProperty("user.dir");

                        String text = s.getMessage(); // 你要编码的文字（非中文）
                        String filePath = rootPath + File.separator + CODE_UUID + "qrcode.png"; // 输出文件的路径
                        System.out.println("------二维码生成成功！------");
                        // 将活码转流
                        BufferedImage bufferedImage = generateQRCodeImage(text, width, height, filePath);
                        // 将图像写入到字节流中，格式为PNG
                        ImageIO.write(bufferedImage, "PNG", os);
                    }
                } catch (WriterException | IOException e) {
                    throw new RuntimeException(e);
                }
                break;
            }
        };

        return os.toByteArray();
    }

    public BufferedImage generateQRCodeImage(String text, int width, int height, String filePath) throws WriterException, IOException {
        Map<EncodeHintType, Object> hints = new HashMap<>();
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L);
        hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
        hints.put(EncodeHintType.MARGIN, 1);// 设置白边大小

        BitMatrix matrix = new MultiFormatWriter().encode(text, BarcodeFormat.QR_CODE, width, height, hints);

        Path path = FileSystems.getDefault().getPath(filePath);
        MatrixToImageWriter.writeToPath(matrix, "PNG", path);

        // 加载图片
        File imageFile = new File(filePath);
        BufferedImage image = ImageIO.read(imageFile);

        // 如果需要，可以在此处理图像（例如缩放、裁剪等）
        // image = resizeImage(image, newWidth, newHeight);

        // 将处理后的图像转换为字节流
//        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        // 将图像写入到字节流中，格式为PNG
//        ImageIO.write(image, "PNG", baos);
        imageFile.delete();
        return image;
    }

    /**
     * 生成8位随机串
     * @return
     */
    private String generateRandomCode() {
        return UUID.randomUUID().toString()
                .replace("-", "")
                .substring(0, CODE_LENGTH);
    }

    @Override
    public Optional findByShortCode(String shortCode) {
        return Optional.empty();
    }
}
